#include "SimplificadorDeTerminos.h"
#include <string>
#include <iostream>

SimplificadorDeTerminos::SimplificadorDeTerminos() {
	this->cantidad_de_doc = 0;
	this->contadores = 0;
	this->cantidad_de_terminos = 0;
}

SimplificadorDeTerminos::~SimplificadorDeTerminos() {
	if ( this->contadores != NULL) {
		delete[] this->contadores;
	}
}

void SimplificadorDeTerminos::simplificar(Termino_Parseado* terminos, int cantidad, const std::string& path_salida) {

	unsigned short int frec = 0;
	int pos_buffer = 0;

	char* buffer = new char[SIZE_BUFFER];
	memset(buffer,0,SIZE_BUFFER);

	FILE* salida = fopen(path_salida.c_str(), "w+");
	Termino_Parseado* ter_actual = new Termino_Parseado;
	memset(ter_actual, 0, sizeof(Termino_Parseado));
	Termino_Parseado* ter_sig = new Termino_Parseado;
	memset(ter_sig,0,sizeof(Termino_Parseado));

	int i = 0;
	frec = 1;

	memcpy(ter_actual, &terminos[i] , sizeof(Termino_Parseado));
	TerminoSimplificado* ter_simp = new TerminoSimplificado(ter_actual);
	bool fin = false;

	while (!fin) {
		i++;
		memset(ter_sig, 0, sizeof(Termino_Parseado));
		memcpy(ter_sig, &terminos[i],  sizeof(Termino_Parseado));
		int comp =  strncmp(ter_actual->termino, ter_sig->termino, 40);
		if (comp!= 0) {
			this->cantidad_de_terminos++;
			ter_simp->agregar_doc(ter_actual->doc, frec);
			this->contadores[ter_actual->doc] = this->contadores[ter_actual->doc] + 1;
			if ( ter_simp->size() + pos_buffer > SIZE_BUFFER ) {
				fwrite(buffer, pos_buffer,sizeof(char),  salida);
				memset(buffer,0,SIZE_BUFFER);
				pos_buffer = 0;
			}

			else {
				ter_simp->grabar(buffer, &pos_buffer);
			}

			delete ter_simp;
			ter_simp = new TerminoSimplificado(ter_sig);
			frec = 1;
		}

		else {
			if (ter_actual->doc != ter_sig->doc) {
				ter_simp->agregar_doc(ter_actual->doc, frec);
				this->contadores[ter_actual->doc] = this->contadores[ter_actual->doc] + 1;
				frec = 1;
			}
			else {
				frec++;
			}
		}
		memcpy(ter_actual,ter_sig,sizeof(Termino_Parseado));
		if (i == (cantidad-1)) {
			fin = true;
			this->cantidad_de_terminos++;
			ter_simp->agregar_doc(ter_actual->doc, frec);
			this->contadores[ter_actual->doc] = this->contadores[ter_actual->doc] + 1;
			if ( ter_simp->size() + pos_buffer > SIZE_BUFFER ) {
				fwrite(buffer,  pos_buffer, sizeof(char), salida);
				memset(buffer,0,SIZE_BUFFER);
				pos_buffer = 0;
			}

			else {
				ter_simp->grabar(buffer, &pos_buffer);
				fwrite(buffer, pos_buffer, sizeof(char) , salida);
			}
			delete ter_simp;
		}
	}
	delete ter_actual;
	delete ter_sig;
	delete[] buffer;
	fclose(salida);
	delete[] terminos;
	FILE* info_doc = fopen(this->path_info_doc.c_str(), "w+");
	fwrite(&this->cantidad_de_terminos, 1, sizeof(int) ,info_doc);
	fwrite(&this->cantidad_de_doc, 1, sizeof(int),info_doc);
	fwrite(this->contadores, this->cantidad_de_doc, sizeof(int), info_doc);
	fclose(info_doc);
}


void SimplificadorDeTerminos::set_info_docs(int cant, const std::string& salida) {
	this->cantidad_de_doc = cant;
	this->path_info_doc = salida;
	this->contadores = new int[cant];
	memset (this->contadores,0,cant*4);
}
